home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-9.10-netbook-remix-PL.iso / casper / filesystem.squashfs / usr / lib / ubiquity / plugins / ubi-console-setup.py next >
Text File  |  2009-09-09  |  28KB  |  652 lines

  1. # -*- coding: utf-8; Mode: Python; indent-tabs-mode: nil; tab-width: 4 -*-
  2.  
  3. # Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd.
  4. # Written by Tollef Fog Heen <tfheen@ubuntu.com> and
  5. # Colin Watson <cjwatson@ubuntu.com>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  
  21. import re
  22. import os
  23.  
  24. from ubiquity.plugin import *
  25. from ubiquity import keyboard_names
  26. from ubiquity import misc
  27.  
  28. NAME = 'console_setup'
  29. AFTER = 'timezone'
  30. WEIGHT = 10
  31.  
  32. class PageGtk(PluginUI):
  33.     def __init__(self, controller, *args, **kwargs):
  34.         self.controller = controller
  35.         self.current_layout = None
  36.         self.default_keyboard_layout = None
  37.         self.default_keyboard_variant = None
  38.         try:
  39.             import gtk
  40.             builder = gtk.Builder()
  41.             builder.add_from_file('/usr/share/ubiquity/gtk/stepKeyboardConf.ui')
  42.             builder.connect_signals(self)
  43.             self.page = builder.get_object('stepKeyboardConf')
  44.             self.suggested_keymap = builder.get_object('suggested_keymap')
  45.             self.suggested_keymap_label = builder.get_object('suggested_keymap_label')
  46.             self.keyboard_layout_hbox = builder.get_object('keyboard_layout_hbox')
  47.             self.keyboardlayoutview = builder.get_object('keyboardlayoutview')
  48.             self.keyboardvariantview = builder.get_object('keyboardvariantview')
  49.         except Exception, e:
  50.             self.debug('Could not create keyboard page: %s', e)
  51.             self.page = None
  52.         self.plugin_widgets = self.page
  53.  
  54.     def on_keyboardlayoutview_row_activated(self, *args):
  55.         self.controller.go_forward()
  56.  
  57.     def on_keyboard_layout_selected(self, *args):
  58.         layout = self.get_keyboard()
  59.         if layout is not None:
  60.             self.current_layout = layout
  61.             self.controller.dbfilter.change_layout(layout)
  62.  
  63.     def on_keyboardvariantview_row_activated(self, *args):
  64.         self.controller.go_forward()
  65.  
  66.     def on_keyboard_variant_selected(self, *args):
  67.         layout = self.get_keyboard()
  68.         variant = self.get_keyboard_variant()
  69.         if layout is not None and variant is not None:
  70.             self.controller.dbfilter.apply_keyboard(layout, variant)
  71.  
  72.     def set_keyboard_choices(self, choices):
  73.         import gtk, gobject
  74.         layouts = gtk.ListStore(gobject.TYPE_STRING)
  75.         self.keyboardlayoutview.set_model(layouts)
  76.         for v in sorted(choices):
  77.             layouts.append([v])
  78.  
  79.         if len(self.keyboardlayoutview.get_columns()) < 1:
  80.             column = gtk.TreeViewColumn("Layout", gtk.CellRendererText(), text=0)
  81.             column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
  82.             self.keyboardlayoutview.append_column(column)
  83.             selection = self.keyboardlayoutview.get_selection()
  84.             selection.connect('changed',
  85.                               self.on_keyboard_layout_selected)
  86.  
  87.         if self.current_layout is not None:
  88.             self.set_keyboard(self.current_layout)
  89.  
  90.     def set_keyboard(self, layout):
  91.         if self.default_keyboard_layout is None:
  92.             self.default_keyboard_layout = layout
  93.         self.current_layout = layout
  94.         model = self.keyboardlayoutview.get_model()
  95.         if model is None:
  96.             return
  97.         iterator = model.iter_children(None)
  98.         while iterator is not None:
  99.             if unicode(model.get_value(iterator, 0)) == layout:
  100.                 path = model.get_path(iterator)
  101.                 self.keyboardlayoutview.get_selection().select_path(path)
  102.                 self.keyboardlayoutview.scroll_to_cell(
  103.                     path, use_align=True, row_align=0.5)
  104.                 break
  105.             iterator = model.iter_next(iterator)
  106.  
  107.     def get_keyboard(self):
  108.         if self.suggested_keymap.get_active():
  109.             if self.default_keyboard_layout is not None:
  110.                 return None
  111.             else:
  112.                 return unicode(self.default_keyboard_layout)
  113.         selection = self.keyboardlayoutview.get_selection()
  114.         (model, iterator) = selection.get_selected()
  115.         if iterator is None:
  116.             return None
  117.         else:
  118.             return unicode(model.get_value(iterator, 0))
  119.  
  120.     def set_keyboard_variant_choices(self, choices):
  121.         import gtk, gobject
  122.         variants = gtk.ListStore(gobject.TYPE_STRING)
  123.         self.keyboardvariantview.set_model(variants)
  124.         for v in sorted(choices):
  125.             variants.append([v])
  126.  
  127.         if len(self.keyboardvariantview.get_columns()) < 1:
  128.             column = gtk.TreeViewColumn("Variant", gtk.CellRendererText(), text=0)
  129.             column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
  130.             self.keyboardvariantview.append_column(column)
  131.             selection = self.keyboardvariantview.get_selection()
  132.             selection.connect('changed',
  133.                               self.on_keyboard_variant_selected)
  134.  
  135.     def set_keyboard_variant(self, variant):
  136.         if self.default_keyboard_variant is None:
  137.             self.default_keyboard_variant = variant
  138.         # Make sure the "suggested option" is selected, otherwise this will
  139.         # change every time the user selects a new keyboard in the manual
  140.         # choice selection boxes.
  141.         if self.suggested_keymap.get_active():
  142.             self.suggested_keymap_label.set_property('label', variant)
  143.             self.suggested_keymap.toggled()
  144.         model = self.keyboardvariantview.get_model()
  145.         if model is None:
  146.             return
  147.         iterator = model.iter_children(None)
  148.         while iterator is not None:
  149.             if unicode(model.get_value(iterator, 0)) == variant:
  150.                 path = model.get_path(iterator)
  151.                 self.keyboardvariantview.get_selection().select_path(path)
  152.                 self.keyboardvariantview.scroll_to_cell(
  153.                     path, use_align=True, row_align=0.5)
  154.                 break
  155.             iterator = model.iter_next(iterator)
  156.  
  157.     def get_keyboard_variant(self):
  158.         if self.suggested_keymap.get_active():
  159.             if self.default_keyboard_variant is None:
  160.                 return None
  161.             else:
  162.                 return unicode(self.default_keyboard_variant)
  163.         selection = self.keyboardvariantview.get_selection()
  164.         (model, iterator) = selection.get_selected()
  165.         if iterator is None:
  166.             return None
  167.         else:
  168.             return unicode(model.get_value(iterator, 0))
  169.  
  170.     def on_suggested_keymap_toggled(self, widget):
  171.         if self.suggested_keymap.get_active():
  172.             self.keyboard_layout_hbox.set_sensitive(False)
  173.             if (self.default_keyboard_layout is not None and
  174.                 self.default_keyboard_variant is not None):
  175.                 self.current_layout = self.default_keyboard_layout
  176.                 self.controller.dbfilter.change_layout(self.default_keyboard_layout)
  177.                 self.controller.dbfilter.apply_keyboard(self.default_keyboard_layout,
  178.                                                         self.default_keyboard_variant)
  179.         else:
  180.             self.keyboard_layout_hbox.set_sensitive(True)
  181.  
  182. class PageKde(PluginUI):
  183.     plugin_breadcrumb = 'ubiquity/text/breadcrumb_keyboard'
  184.  
  185.     def __init__(self, controller, *args, **kwargs):
  186.         self.controller = controller
  187.         self.current_layout = None
  188.         self.default_keyboard_layout = None
  189.         self.default_keyboard_variant = None
  190.         try:
  191.             from PyQt4 import uic
  192.             from PyQt4.QtGui import QVBoxLayout
  193.             from ubiquity.frontend.kde_components.Keyboard import Keyboard
  194.             self.page = uic.loadUi('/usr/share/ubiquity/qt/stepKeyboardConf.ui')
  195.             self.keyboardDisplay = Keyboard(self.page.keyboard_frame)
  196.             self.page.keyboard_frame.setLayout(QVBoxLayout())
  197.             self.page.keyboard_frame.layout().addWidget(self.keyboardDisplay)
  198.             #use activated instead of changed because we only want to act when the user changes the selection
  199.             #not when we are populating the combo box
  200.             self.page.keyboard_layout_combobox.activated.connect(self.on_keyboard_layout_selected)
  201.             self.page.keyboard_variant_combobox.activated.connect(self.on_keyboard_variant_selected)
  202.         except Exception, e:
  203.             self.debug('Could not create keyboard page: %s', e)
  204.             self.page = None
  205.         self.plugin_widgets = self.page
  206.  
  207.     def on_keyboard_layout_selected(self):
  208.         layout = self.get_keyboard()
  209.         if layout is not None:
  210.             #skip updating keyboard if not using display
  211.             if self.keyboardDisplay:
  212.                 ly = keyboard_names.layouts[unicode(layout)]
  213.                 self.keyboardDisplay.setLayout(ly)
  214.             
  215.                 #no variants, force update by setting none
  216.                 #if not keyboard_names.variants.has_key(ly):
  217.                 #    self.keyboardDisplay.setVariant(None)
  218.             
  219.             self.current_layout = layout
  220.             self.controller.dbfilter.change_layout(layout)
  221.  
  222.     def on_keyboard_variant_selected(self):
  223.         layout = self.get_keyboard()
  224.         variant = self.get_keyboard_variant()
  225.         
  226.         if self.keyboardDisplay:
  227.             var = None
  228.             ly = keyboard_names.layouts[layout]
  229.             if variant and keyboard_names.variants.has_key(ly):
  230.                 variantMap = keyboard_names.variants[ly]
  231.                 var = variantMap[unicode(variant)]
  232.             
  233.             self.keyboardDisplay.setVariant(var)
  234.         
  235.         if layout is not None and variant is not None:
  236.             self.controller.dbfilter.apply_keyboard(layout, variant)
  237.  
  238.     def set_keyboard_choices(self, choices):
  239.         from PyQt4.QtCore import QString
  240.         self.page.keyboard_layout_combobox.clear()
  241.         for choice in sorted(choices):
  242.             self.page.keyboard_layout_combobox.addItem(QString(unicode(choice)))
  243.  
  244.         if self.current_layout is not None:
  245.             self.set_keyboard(self.current_layout)
  246.  
  247.     def set_keyboard (self, layout):
  248.         from PyQt4.QtCore import QString
  249.         index = self.page.keyboard_layout_combobox.findText(QString(unicode(layout)))
  250.         
  251.         if index > -1:
  252.             self.page.keyboard_layout_combobox.setCurrentIndex(index)
  253.         
  254.         if self.keyboardDisplay:
  255.             ly = keyboard_names.layouts[unicode(layout)]
  256.             self.keyboardDisplay.setLayout(ly)
  257.  
  258.     def get_keyboard(self):
  259.         if self.page.keyboard_layout_combobox.currentIndex() < 0:
  260.             return None
  261.             
  262.         return unicode(self.page.keyboard_layout_combobox.currentText())
  263.  
  264.     def set_keyboard_variant_choices(self, choices):
  265.         from PyQt4.QtCore import QString
  266.         self.page.keyboard_variant_combobox.clear();
  267.         for choice in sorted(choices):
  268.             self.page.keyboard_variant_combobox.addItem(QString(unicode(choice)))
  269.  
  270.     def set_keyboard_variant(self, variant):
  271.         from PyQt4.QtCore import QString
  272.         index = self.page.keyboard_variant_combobox.findText(QString(unicode(variant)))
  273.         
  274.         if index > -1:
  275.             self.page.keyboard_variant_combobox.setCurrentIndex(index)
  276.         
  277.         if self.keyboardDisplay:
  278.             var = None
  279.             layout = keyboard_names.layouts[self.get_keyboard()]
  280.             if variant and keyboard_names.variants.has_key(layout):
  281.                 variantMap = keyboard_names.variants[layout]
  282.                 var = variantMap[unicode(variant)]
  283.             
  284.             self.keyboardDisplay.setVariant(var)
  285.     
  286.     def get_keyboard_variant(self):
  287.         if self.page.keyboard_variant_combobox.currentIndex() < 0:
  288.             return None
  289.             
  290.         return unicode(self.page.keyboard_variant_combobox.currentText())
  291.  
  292. class PageDebconf(PluginUI):
  293.     plugin_title = 'ubiquity/text/keyboard_heading_label'
  294.  
  295. class PageNoninteractive(PluginUI):
  296.     def set_keyboard_choices(self, choices):
  297.         """Set the available keyboard layout choices."""
  298.         pass
  299.  
  300.     def set_keyboard(self, layout):
  301.         """Set the current keyboard layout."""
  302.         self.current_layout = layout
  303.  
  304.     def get_keyboard(self):
  305.         """Get the current keyboard layout."""
  306.         return self.current_layout
  307.  
  308.     def set_keyboard_variant_choices(self, choices):
  309.         """Set the available keyboard variant choices."""
  310.         pass
  311.  
  312.     def set_keyboard_variant(self, variant):
  313.         """Set the current keyboard variant."""
  314.         self.keyboard_variant = variant
  315.  
  316.     def get_keyboard_variant(self):
  317.         #print '*** get_keyboard_variant'
  318.         return self.keyboard_variant
  319.  
  320. class Page(Plugin):
  321.     def prepare(self, unfiltered=False):
  322.         self.preseed('console-setup/ask_detect', 'false')
  323.  
  324.         # We need to get rid of /etc/default/console-setup, or console-setup
  325.         # will think it's already configured and behave differently. Try to
  326.         # save the old file for interest's sake, but it's not a big deal if
  327.         # we can't.
  328.         misc.regain_privileges()
  329.         try:
  330.             os.unlink('/etc/default/console-setup.pre-ubiquity')
  331.         except OSError:
  332.             pass
  333.         try:
  334.             os.rename('/etc/default/console-setup',
  335.                       '/etc/default/console-setup.pre-ubiquity')
  336.         except OSError:
  337.             try:
  338.                 os.unlink('/etc/default/console-setup')
  339.             except OSError:
  340.                 pass
  341.         misc.drop_privileges()
  342.         # Make sure debconf doesn't do anything with crazy "preseeded"
  343.         # answers to these questions. If you want to preseed these, use the
  344.         # *code variants.
  345.         self.db.fset('console-setup/layout', 'seen', 'false')
  346.         self.db.fset('console-setup/variant', 'seen', 'false')
  347.         self.db.fset('console-setup/model', 'seen', 'false')
  348.         self.db.fset('console-setup/codeset', 'seen', 'false')
  349.  
  350.         # Technically we should provide a version as the second argument,
  351.         # but that isn't currently needed and it would require querying
  352.         # apt/dpkg for the current version, which would be slow, so we don't
  353.         # bother for now.
  354.         return (['/usr/lib/ubiquity/console-setup/console-setup.postinst',
  355.                  'configure'],
  356.                 ['^console-setup/layout', '^console-setup/variant',
  357.                  '^console-setup/unsupported_'],
  358.                 {'OVERRIDE_ALLOW_PRESEEDING': '1'})
  359.  
  360.     def run(self, priority, question):
  361.         if self.done:
  362.             return self.succeeded
  363.  
  364.         if question == 'console-setup/layout':
  365.             # Reset this in case we just backed up from the variant
  366.             # question.
  367.             self.succeeded = True
  368.             # TODO cjwatson 2006-09-07: no console-setup support for layout
  369.             # choice translation yet
  370.             self.ui.set_keyboard_choices(
  371.                 self.choices_untranslated(question))
  372.             self.ui.set_keyboard(self.db.get(question))
  373.             return True
  374.         elif question == 'console-setup/variant':
  375.             # TODO cjwatson 2006-10-02: no console-setup support for variant
  376.             # choice translation yet
  377.             self.ui.set_keyboard_variant_choices(
  378.                 self.choices_untranslated(question))
  379.             self.ui.set_keyboard_variant(self.db.get(question))
  380.             # console-setup preseeding is special, and needs to be checked
  381.             # by hand. The seen flag on console-setup/layout is used
  382.             # internally by console-setup, so we can't just force it to
  383.             # true.
  384.             if ('UBIQUITY_AUTOMATIC' in os.environ and
  385.                 self.db.fget('console-setup/layoutcode', 'seen') == 'true'):
  386.                 return True
  387.             else:
  388.                 return Plugin.run(self, priority, question)
  389.         elif question.startswith('console-setup/unsupported_'):
  390.             response = self.frontend.question_dialog(
  391.                 self.description(question),
  392.                 self.extended_description(question),
  393.                 ('ubiquity/imported/yes', 'ubiquity/imported/no'))
  394.             if response is None or response == 'ubiquity/imported/yes':
  395.                 self.preseed(question, 'true')
  396.             else:
  397.                 self.preseed(question, 'false')
  398.             return True
  399.         else:
  400.             return True
  401.  
  402.     def change_layout(self, layout):
  403.         self.preseed('console-setup/layout', layout)
  404.         # Back up in order to get console-setup to recalculate the list of
  405.         # possible variants.
  406.         self.succeeded = False
  407.         self.exit_ui_loops()
  408.  
  409.     def ok_handler(self):
  410.         variant = self.ui.get_keyboard_variant()
  411.         if variant is not None:
  412.             self.preseed('console-setup/variant', variant)
  413.         return Plugin.ok_handler(self)
  414.  
  415.     # TODO cjwatson 2006-09-07: This is duplication from console-setup, but
  416.     # currently difficult to avoid; we need to apply the keymap immediately
  417.     # when the user selects it in the UI (and before they move to the next
  418.     # page), so this needs to be fast and moving through console-setup to
  419.     # get the corrections it applies will be too slow.
  420.     def adjust_keyboard(self, model, layout, variant, options):
  421.         """Apply any necessary tweaks to the supplied model, layout, variant,
  422.         and options."""
  423.  
  424.         if layout in ('am', 'ara', 'ben', 'bd', 'bg', 'bt', 'by', 'deva', 'ge',
  425.                       'gh', 'gr', 'guj', 'guru', 'il', 'in', 'ir', 'iku',
  426.                       'kan', 'kh', 'kz', 'la', 'lao', 'lk', 'mk', 'mm', 'mn',
  427.                       'mv', 'mal', 'ori', 'pk', 'ru', 'scc', 'sy', 'syr',
  428.                       'tel', 'th', 'tj', 'tam', 'ua', 'uz'):
  429.             latin = False
  430.             real_layout = 'us,%s' % layout
  431.         elif layout == 'jp':
  432.             if variant in ('106', 'common', 'OADG109A', 'nicola_f_bs', ''):
  433.                 latin = True
  434.                 real_layout = layout
  435.             else:
  436.                 latin = False
  437.                 real_layout = 'jp,jp'
  438.         elif layout == 'lt':
  439.             latin = False
  440.             real_layout = 'lt,lt'
  441.         elif layout == 'me':
  442.             if variant == 'basic' or variant.startswith('latin'):
  443.                 latin = True
  444.                 real_layout = layout
  445.             else:
  446.                 latin = False
  447.                 real_layout = 'me,me'
  448.         elif layout == 'rs':
  449.             if variant == 'basic' or variant.startswith('latin'):
  450.                 latin = True
  451.                 real_layout = layout
  452.             else:
  453.                 latin = False
  454.                 real_layout = 'rs,rs'
  455.         else:
  456.             latin = True
  457.             real_layout = layout
  458.  
  459.         if latin:
  460.             real_variant = variant
  461.         elif real_layout == 'jp,jp':
  462.             real_variant = '106,%s' % variant
  463.         elif real_layout == 'lt,lt':
  464.             if variant == 'us':
  465.                 real_variant = 'us,'
  466.             else:
  467.                 real_variant = '%s,us' % variant
  468.         elif real_layout == 'me,me':
  469.             if variant == 'cyrillicyz':
  470.                 real_variant = 'latinyz,%s' % variant
  471.             elif variant == 'cyrillicalternatequotes':
  472.                 real_variant = 'latinalternatequotes,%s' % variant
  473.             else:
  474.                 real_variant = 'basic,%s' % variant
  475.         elif real_layout == 'rs,rs':
  476.             if variant == 'yz':
  477.                 real_variant = 'latinyz,%s' % variant
  478.             elif variant == 'alternatequotes':
  479.                 real_variant = 'latinalternatequotes,%s' % variant
  480.             else:
  481.                 real_variant = 'latin,%s' % variant
  482.         else:
  483.             real_variant = ',%s' % variant
  484.  
  485.         real_options = [opt for opt in options if not opt.startswith('lv3:')]
  486.         if not latin:
  487.             toggle = re.compile(r'^grp:.*toggle$')
  488.             real_options = [opt for opt in real_options
  489.                                 if not toggle.match(opt)]
  490.             # TODO cjwatson 2006-09-07: honour crazy preseeding; probably
  491.             # not quite right, especially for Apples which may need a level
  492.             # 3 shift
  493.             real_options.append('grp:alt_shift_toggle')
  494.         if layout != 'us':
  495.             real_options.append('lv3:ralt_switch')
  496.  
  497.         real_model = model
  498.         if model == 'pc105':
  499.             if real_layout == 'br':
  500.                 real_model = 'abnt2'
  501.             elif real_layout == 'jp':
  502.                 real_model = 'jp106'
  503.  
  504.         return (real_model, real_layout, real_variant, real_options)
  505.  
  506.     def apply_keyboard(self, layout, variant):
  507.         model = self.db.get('console-setup/modelcode')
  508.  
  509.         if layout not in keyboard_names.layouts:
  510.             self.debug("Unknown keyboard layout '%s'" % layout)
  511.             return
  512.         layout = keyboard_names.layouts[layout]
  513.  
  514.         if layout not in keyboard_names.variants:
  515.             self.debug("No known variants for layout '%s'" % layout)
  516.             variant = ''
  517.         elif variant in keyboard_names.variants[layout]:
  518.             variant = keyboard_names.variants[layout][variant]
  519.         else:
  520.             self.debug("Unknown keyboard variant '%s' for layout '%s'" %
  521.                        (variant, layout))
  522.             return
  523.  
  524.         (model, layout, variant, options) = \
  525.             self.adjust_keyboard(model, layout, variant, [])
  526.         self.debug("Setting keyboard layout: %s %s %s %s" %
  527.                    (model, layout, variant, options))
  528.         self.apply_real_keyboard(model, layout, variant, options)
  529.  
  530.     def apply_real_keyboard(self, model, layout, variant, options):
  531.         args = []
  532.         if model is not None and model != '':
  533.             args.extend(("-model", model))
  534.         args.extend(("-layout", layout))
  535.         if variant != '':
  536.             args.extend(("-variant", variant))
  537.         args.extend(("-option", ""))
  538.         for option in options:
  539.             args.extend(("-option", option))
  540.         misc.execute("setxkbmap", *args)
  541.  
  542.     def cleanup(self):
  543.         # TODO cjwatson 2006-09-07: I'd use dexconf, but it seems reasonable
  544.         # for somebody to edit /etc/X11/xorg.conf on the live CD and expect
  545.         # that to be carried over to the installed system (indeed, we've
  546.         # always supported that up to now). So we get this horrible mess
  547.         # instead ...
  548.  
  549.         model = self.db.get('console-setup/modelcode')
  550.         layout = self.db.get('console-setup/layoutcode')
  551.         variant = self.db.get('console-setup/variantcode')
  552.         options = self.db.get('console-setup/optionscode')
  553.         self.apply_real_keyboard(model, layout, variant, options.split(','))
  554.  
  555.         Plugin.cleanup(self)
  556.  
  557.         if layout == '':
  558.             return
  559.  
  560.         misc.regain_privileges()
  561.         oldconfigfile = '/etc/X11/xorg.conf'
  562.         newconfigfile = '/etc/X11/xorg.conf.new'
  563.         try:
  564.             oldconfig = open(oldconfigfile)
  565.         except IOError:
  566.             # Did they remove /etc/X11/xorg.conf or something? Oh well,
  567.             # better to carry on than to crash.
  568.             return
  569.         newconfig = open(newconfigfile, 'w')
  570.  
  571.         re_section_inputdevice = re.compile(r'\s*Section\s+"InputDevice"\s*$')
  572.         re_driver_kbd = re.compile(r'\s*Driver\s+"kbd"\s*$')
  573.         re_endsection = re.compile(r'\s*EndSection\s*$')
  574.         re_option_xkbmodel = re.compile(r'(\s*Option\s*"XkbModel"\s*).*')
  575.         re_option_xkblayout = re.compile(r'(\s*Option\s*"XkbLayout"\s*).*')
  576.         re_option_xkbvariant = re.compile(r'(\s*Option\s*"XkbVariant"\s*).*')
  577.         re_option_xkboptions = re.compile(r'(\s*Option\s*"XkbOptions"\s*).*')
  578.         in_inputdevice = False
  579.         in_inputdevice_kbd = False
  580.         done = {'model': model == '', 'layout': False,
  581.                 'variant': variant == '', 'options': options == ''}
  582.  
  583.         for line in oldconfig:
  584.             line = line.rstrip('\n')
  585.             if re_section_inputdevice.match(line) is not None:
  586.                 in_inputdevice = True
  587.             elif in_inputdevice and re_driver_kbd.match(line) is not None:
  588.                 in_inputdevice_kbd = True
  589.             elif re_endsection.match(line) is not None:
  590.                 if in_inputdevice_kbd:
  591.                     if not done['model']:
  592.                         print >>newconfig, ('\tOption\t\t"XkbModel"\t"%s"' %
  593.                                             model)
  594.                     if not done['layout']:
  595.                         print >>newconfig, ('\tOption\t\t"XkbLayout"\t"%s"' %
  596.                                             layout)
  597.                     if not done['variant']:
  598.                         print >>newconfig, ('\tOption\t\t"XkbVariant"\t"%s"' %
  599.                                             variant)
  600.                     if not done['options']:
  601.                         print >>newconfig, ('\tOption\t\t"XkbOptions"\t"%s"' %
  602.                                             options)
  603.                 in_inputdevice = False
  604.                 in_inputdevice_kbd = False
  605.                 done = {'model': model == '', 'layout': False,
  606.                         'variant': variant == '', 'options': options == ''}
  607.             elif in_inputdevice_kbd:
  608.                 match = re_option_xkbmodel.match(line)
  609.                 if match is not None:
  610.                     if model == '':
  611.                         # hmm, not quite sure what to do here; guessing that
  612.                         # forcing to pc105 will be reasonable
  613.                         line = match.group(1) + '"pc105"'
  614.                     else:
  615.                         line = match.group(1) + '"%s"' % model
  616.                     done['model'] = True
  617.                 else:
  618.                     match = re_option_xkblayout.match(line)
  619.                     if match is not None:
  620.                         line = match.group(1) + '"%s"' % layout
  621.                         done['layout'] = True
  622.                     else:
  623.                         match = re_option_xkbvariant.match(line)
  624.                         if match is not None:
  625.                             if variant == '':
  626.                                 continue # delete this line
  627.                             else:
  628.                                 line = match.group(1) + '"%s"' % variant
  629.                             done['variant'] = True
  630.                         else:
  631.                             match = re_option_xkboptions.match(line)
  632.                             if match is not None:
  633.                                 if options == '':
  634.                                     continue # delete this line
  635.                                 else:
  636.                                     line = match.group(1) + '"%s"' % options
  637.                                 done['options'] = True
  638.             print >>newconfig, line
  639.  
  640.         newconfig.close()
  641.         oldconfig.close()
  642.         os.rename(newconfigfile, oldconfigfile)
  643.         misc.drop_privileges()
  644.  
  645. class Install(InstallPlugin):
  646.     def prepare(self, unfiltered=False):
  647.         return (['/usr/share/ubiquity/console-setup-apply'], [])
  648.  
  649.     def install(self, target, progress, *args, **kwargs):
  650.         progress.info('ubiquity/install/keyboard')
  651.         return InstallPlugin.install(self, target, progress, *args, **kwargs)
  652.